package cn.jfast.expand.wx.api.core;

import cn.jfast.expand.wx.aes.AesException;
import cn.jfast.expand.wx.aes.SHA1;
import cn.jfast.expand.wx.api.consts.WxMsgType;
import cn.jfast.expand.wx.api.msg.MPAct;
import cn.jfast.expand.wx.api.msg.OutPutMsg;
import cn.jfast.expand.wx.api.msg.PicInfo;
import cn.jfast.expand.wx.api.msg.ReceiveMsg;
import cn.jfast.framework.log.LogFactory;
import cn.jfast.framework.log.LogType;
import cn.jfast.framework.log.Logger;

/**
 * 默认的微信消息处理器
 */
public class WxMsgApiHandler implements WxMsgApi {

    private static final Logger log = LogFactory.getLogger(LogType.JFast,WxMsgApiHandler.class);
    
    private MPAct mpAct;
    
    private WxApiHandler wxApi;
    
    private WxOpenApiHandler wxOpenApi;
    
    public void init(String mpKey){
    	this.wxApi = new WxApiHandler(mpKey);
    	this.wxOpenApi = new WxOpenApiHandler(mpKey);
    	this.mpAct = MpActHolder.getMpAct(mpKey);
    }
    
    public MPAct getMPAct(){
    	return this.mpAct;
    }
    
    public WxApiHandler getWxApi(){
    	return this.wxApi;
    }
    
    public WxOpenApiHandler getWxOpenApi(){
    	return this.wxOpenApi;
    }
    
    @Override
    public boolean check(String token,
                        String signature,
                        String timestamp,
                        String nonce) throws AesException {

        if (null == signature
                || signature.length() > 128
                || null == timestamp
                || timestamp.length() > 128
                || null == nonce
                || nonce.length() > 128) {
            log.error("验证签名参数失败!!!");
            log.error("signature=%s,timestamp=%s,nonce=%s", signature, timestamp, nonce);
            return false;
        }

        if (log.isInfoEnable()) {
           log.info("微信接入URL验证成功...");
           log.info("signature=%s,timestamp=%s,nonce=%s", signature, timestamp, nonce);
        }

        String s = SHA1.calculate(token, timestamp, nonce);
        if (s.equals(signature)){
            return true;
        }

        return false;
    }


    @Override
    public OutPutMsg def(ReceiveMsg rm) {
        OutPutMsg om = new OutPutMsg(rm);
        om.setMsgType(WxMsgType.text.name());
        om.setContent("新的功能消息,消息类型为:"+rm.getMsgType());
        if (log.isInfoEnable()) {
            log.info("微信新类型消息!!!");
            log.info("msgid=%s, from=%s,to=%s,msgtype=%s", rm.getMsgId(),
                    rm.getFromUserName(), rm.getTotalCnt(), rm.getMsgType());
        }
        return om;
    }

    @Override
    public OutPutMsg text(ReceiveMsg rm) {
        OutPutMsg om = new OutPutMsg(rm);
        om.setMsgType(rm.getMsgType());
        om.setContent(rm.getContent() + "\n您的消息已经收到[微笑]");
        if (log.isInfoEnable()) {
            log.info("接收到微信文本消息...");
            log.info("msgid=%s, from=%s, to=%s, content=%s", rm.getMsgId(),
                    rm.getFromUserName(), rm.getToUserName(), rm.getContent());
        }
        return om;
    }

    @Override
    public OutPutMsg image(ReceiveMsg rm) {
        OutPutMsg om = new OutPutMsg(rm);
        om.setMsgType(rm.getMsgType());
        om.setMediaId(rm.getMediaId());
        if (log.isInfoEnable()) {
            log.info("接收到微信图像消息...");
            log.info("msgid=%s, from=%s, to=%s, mediaid=%s", rm.getMsgId(),
                    rm.getFromUserName(), rm.getToUserName(), rm.getMediaId());
        }
        return om;
    }

    @Override
    public OutPutMsg voice(ReceiveMsg rm) {
        OutPutMsg om = new OutPutMsg(rm);
        if (null != rm.getRecognition()) {
            om.setMsgType(WxMsgType.text.name());
            om.setContent("您的语音消息已接收.[微笑]\n内容为："+rm.getRecognition());
        } else {
            om.setMsgType(rm.getMsgType());
            om.setMediaId(rm.getMediaId());
        }
        if (log.isInfoEnable()) {
            log.info("接收到音频消息...");
            log.info("msgid=%s, from=%s, to=%s, mediaid=%s, trans=%s", rm.getMsgId(),
                    rm.getFromUserName(), rm.getToUserName(), rm.getMediaId(), rm.getRecognition());
        }
        return om;
    }

    @Override
    public OutPutMsg video(ReceiveMsg rm) {
        OutPutMsg om = new OutPutMsg(rm);
        om.setMsgType(rm.getMsgType());
        om.setMediaId(rm.getMediaId());
        if (log.isInfoEnable()) {
            log.info("接收到视频消息...");
            log.info("msgid=%s, from=%s, to=%s, mediaid=%s, thumbmid=%s", rm.getMsgId(),
                    rm.getFromUserName(), rm.getToUserName(), rm.getMediaId(), rm.getThumbMediaId());
        }
        return om;
    }

    @Override
    public OutPutMsg location(ReceiveMsg rm) {
        OutPutMsg om = new OutPutMsg(rm);
        om.setMsgType(WxMsgType.text.name());
        om.setContent("您当前的位置:"+rm.getLabel()+
                ",坐标:["+rm.getLatitude()+","+rm.getLongitude()+
                "],地图缩放级别:"+rm.getScale());
        if (log.isInfoEnable()) {
            log.info("接收到地理位置消息...");
            log.info("msgid=%s, from=%s, to=%s, x=%s, y=%s, scale=%s, label=%s",
                    rm.getMsgId(), rm.getFromUserName(), rm.getToUserName(),
                    rm.getLatitude(), rm.getLongitude(), rm.getScale(), rm.getLabel());
        }
        return om;
    }

    @Override
    public OutPutMsg link(ReceiveMsg rm) {
        OutPutMsg om = new OutPutMsg(rm);
        om.setMsgType(WxMsgType.text.name());
        om.setContent(rm.getTitle()+"\n<a href=\""+rm.getUrl()+"\">点击打开</a>");
        if (log.isInfoEnable()) {
            log.info("接收到链接消息...");
            log.info("msgid=%s, from=%s, to=%s, title=%s, desc=%s, url=%s",
                    rm.getMsgId(), rm.getFromUserName(), rm.getToUserName(),
                    rm.getTitle(), rm.getDescription(), rm.getUrl());
        }
        return om;
    }

    @Override
    public OutPutMsg eClick(ReceiveMsg rm) {
        OutPutMsg om = new OutPutMsg(rm);
        om.setMsgType(WxMsgType.text.name());
        om.setContent("MENU_CLICK:"+rm.getEventKey());
        if (log.isInfoEnable()) {
            log.info("接收到菜单点击消息...");
            log.info("from=%s, to=%s, event=%s, key=%s",
                    rm.getFromUserName(), rm.getToUserName(), rm.getEvent(), rm.getEventKey());
        }
        return om;
    }

    @Override
    public void eView(ReceiveMsg rm) {
        if (log.isInfoEnable()) {
            log.info("接收到菜单视图跳转消息...");
            log.info("from=%s, to=%s, event=%s, key=%s",
                    rm.getFromUserName(), rm.getToUserName(), rm.getEvent(), rm.getEventKey());
        }
    }

    @Override
    public OutPutMsg eSub(ReceiveMsg rm) {
        OutPutMsg om = new OutPutMsg(rm);
        om.setMsgType(WxMsgType.text.name());
        om.setContent("做人最重要的是要有自信，记得每天起床时，在镜子前对自己说，你很好，你可以的，树立生活自信，你可以的！");
        if (log.isInfoEnable()) {
            log.info("接收到订阅消息...");
            log.info("from=%s, to=%s, event=%s",
                    rm.getFromUserName(), rm.getToUserName(), rm.getEvent());
        }
        return om;
    }

    @Override
    public void eUnSub(ReceiveMsg rm) {
        if (log.isInfoEnable()) {
            log.info("接收到退订消息...");
            log.info("from=%s, to=%s, event=%s",
                    rm.getFromUserName(), rm.getToUserName(), rm.getEvent());
        }
    }

    @Override
    public void eScan(ReceiveMsg rm) {
        if (log.isInfoEnable()) {
            log.info("接收到扫描消息...");
            log.info("msgid=%s, from=%s, to=%s, event=%s, key=%s, ticket=%s",
                    rm.getMsgId(), rm.getFromUserName(), rm.getToUserName(),
                    rm.getEvent(), rm.getEventKey(), rm.getTicket());
        }
    }

    @Override
    public void eLocation(ReceiveMsg rm) {
        if (log.isInfoEnable()) {
            log.info("接收到地理位置消息...");
            log.info("msgid=%s, from=%s, to=%s, x=%s, y=%s, precision=%s",
                    rm.getMsgId(), rm.getFromUserName(), rm.getToUserName(),
                    rm.getLatitude(), rm.getLongitude(), rm.getPrecision());
        }
    }

    @Override
    public OutPutMsg eScanCodePush(ReceiveMsg rm) {
        OutPutMsg om = new OutPutMsg(rm);
        om.setMsgType(WxMsgType.text.name());
        String content = "您此次用二维码扫描菜单["+rm.getEventKey()+"],扫描结果为: "+rm.getScanResult();
        om.setContent(content);
        if (log.isInfoEnable()) {
            log.info("接收到二维码扫描事件消息...");
            log.info("msgid=%s, from=%s, to=%s, eventKey=%s, scantype=%s, scanresult=%s",
                    rm.getMsgId(), rm.getFromUserName(),
                    rm.getToUserName(), rm.getEventKey(),
                    rm.getScanType(), rm.getScanResult());
        }
        return om;
    }

    @Override
    public OutPutMsg eScanCodeWait(ReceiveMsg rm) {
        OutPutMsg om = new OutPutMsg(rm);
        om.setMsgType(WxMsgType.text.name());
        String content = "您此次用扫描等待菜单["+rm.getEventKey()+"],扫描结果为: "+rm.getScanResult();
        om.setContent(content);
        if (log.isInfoEnable()) {
            log.info("接收到扫码推事件且弹出“消息接收中”提示消息...");
            log.info("msgid=%s, from=%s, to=%s, eventKey=%s, scantype=%s, scanresult=%s",
                    rm.getMsgId(), rm.getFromUserName(),
                    rm.getToUserName(), rm.getEventKey(),
                    rm.getScanType(), rm.getScanResult());
        }
        return om;
    }

    @Override
    public OutPutMsg ePicSysPhoto(ReceiveMsg rm) {
        OutPutMsg om = new OutPutMsg(rm);
        om.setMsgType(WxMsgType.text.name());
        String content = "您此次用系统拍照["+rm.getEventKey()+"]共发了"+rm.getCount()+"张图片,图片的MD5值为: ";
        for (PicInfo pic : rm.getPicList()) {
            content += pic.getPicMd5Sum() + ", ";
        }
        om.setContent(content.substring(0, content.lastIndexOf(",")));
        if (log.isInfoEnable()) {
            log.info("接收到菜单弹出系统拍照发图消息...");
            log.info("msgid=%s, from=%s, to=%s, eventkey=%s count=%s, picmd5sum=%s",
                    rm.getMsgId(), rm.getFromUserName(),
                    rm.getToUserName(), rm.getEventKey(),
                    rm.getCount(), String.valueOf(rm.getPicList()));
        }
        return om;
    }

    @Override
    public OutPutMsg ePicPhotoOrAlbum(ReceiveMsg rm) {
        OutPutMsg om = new OutPutMsg(rm);
        om.setMsgType(WxMsgType.text.name());
        String content = "您此次用拍照或相册["+rm.getEventKey()+"]共发了"+rm.getCount()+"张图片,图片的MD5值为: ";
        for (PicInfo pic : rm.getPicList()) {
            content += pic.getPicMd5Sum() + ", ";
        }
        om.setContent(content.substring(0, content.lastIndexOf(",")));
        if (log.isInfoEnable()) {
            log.info("接收到菜单弹出拍照或者相册发图消息...");
            log.info("msgid=%s, from=%s, to=%s, eventkey=%s, count=%s, picmd5sum=%s",
                    rm.getMsgId(), rm.getFromUserName(),
                    rm.getToUserName(), rm.getEventKey(),
                    rm.getCount(), String.valueOf(rm.getPicList()));
        }
        return om;
    }

    @Override
    public OutPutMsg ePicWeixin(ReceiveMsg rm) {
        OutPutMsg om = new OutPutMsg(rm);
        om.setMsgType(WxMsgType.text.name());
        String content = "您此次用微信相册["+rm.getEventKey()+"]共发了"+rm.getCount()+"张图片,图片的MD5值为: ";
        for (PicInfo pic : rm.getPicList()) {
            content += pic.getPicMd5Sum() + ", ";
        }
        om.setContent(content.substring(0, content.lastIndexOf(",")));
        if (log.isInfoEnable()) {
            log.info("接收到菜单微信相册发图消息...");
            log.info("msgid=%s, from=%s, to=%s, eventkey=%s, count=%s, picmd5sum=%s",
                    rm.getMsgId(), rm.getFromUserName(),
                    rm.getToUserName(), rm.getEventKey(),
                    rm.getCount(), String.valueOf(rm.getPicList()));
        }
        return om;
    }

    @Override
    public OutPutMsg eLocationSelect(ReceiveMsg rm) {
        OutPutMsg om = new OutPutMsg(rm);
        om.setMsgType(WxMsgType.text.name());
        om.setContent("菜单值:"+rm.getEventKey()+",您当前的位置:"+rm.getLabel()+
                ",坐标:["+rm.getLatitude()+","+rm.getLongitude()+
                "],地图缩放级别:"+rm.getScale()+",朋友圈:"+rm.getPoiName());
        if (log.isInfoEnable()) {
            log.info("接收到菜单地理位置消息...");
            log.info("msgid=%s, from=%s, eventkey=%s, to=%s, " +
                            "x=%s, y=%s, precision=%s, label=%s, poiname=%s",
                    rm.getMsgId(), rm.getFromUserName(),
                    rm.getEventKey(), rm.getToUserName(),
                    rm.getLatitude(), rm.getLongitude(),
                    rm.getPrecision(), rm.getLabel(), rm.getPoiName());
        }
        return om;
    }

    @Override
    public void eTemplateFinish(ReceiveMsg rm) {
       if (log.isInfoEnable()) {
            log.info("接收到模板推送消息...");
            log.info("from=%s, to=%s, msgid=%s, status=%s",
                    rm.getFromUserName(), rm.getToUserName(), rm.getMsgId(), rm.getStatus());
        }
    }

    @Override
    public void eSendJobFinish(ReceiveMsg rm) {
        if (log.isInfoEnable()) {
            log.info("接收到群发推送消息...");
            log.info("from=%s, to=%s, msgid=%s, status=%s, total=%s, filter=%s, sent=%s, err=%s",
                    rm.getFromUserName(), rm.getToUserName(), rm.getMsgId(), rm.getStatus(),
                    rm.getTotalCnt(), rm.getFilterCnt(), rm.getSentCnt(), rm.getErrorCnt());
        }
    }

    @Override
    public void eComponentVerifyTicket(ReceiveMsg rm) {
        if (log.isDebugEnable()) {
            log.info("接收到微信开放平台推送的组件Ticket消息...");
            log.info("appid=%s, infotype=%s, ticket=%s", rm.getAppId(), rm.getInfoType(), rm.getTicket());
        }
    }

    @Override
    public void eUnAuthorizerMP(ReceiveMsg rm) {
        if (log.isDebugEnable()) {
            log.info("接收到微信开放平台推送的公众号取消授权消息...");
            log.info("appid=%s, infotype=%s, unauthorizerappid=%s", rm.getAppId(), rm.getInfoType(), rm.getUnAuthAppid());
        }
    }
}
